package xeroxware.framework.xplatform;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.tobesoft.xplatform.tx.PlatformException;

import xeroxware.framework.exception.ApplicationException;
import xeroxware.framework.exception.PermissionException;

/**
 * <pre>
 * XplatformExceptionResolver
 * </pre>
 * 
 * @since 2013. 1. 9.
 * @author XEROXER
 */
public class XplatformExceptionResolver implements HandlerExceptionResolver {

	@Autowired
	private MessageSourceAccessor msgSrcAccessor;

	@Value("#{contextProperties['xplatform.dto.id']}")
	private String xpDtoId;

	private static final Logger logger = LoggerFactory.getLogger(XplatformExceptionResolver.class);

	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception exception) {

		ModelAndView mav;

		if (request.getHeader("user-agent").indexOf("XPLATFORM") >= 0) {
			mav = new ModelAndView("xplatformView");
			XplatformDTO outDTO = new XplatformDTO();

			if (exception instanceof ApplicationException) {
				ApplicationException bomsEx = (ApplicationException) exception;

				logger.error("[ApplicationException] {}", bomsEx.getMessage(), bomsEx);

				outDTO.setResultMessage(bomsEx.getErrorCode(), bomsEx.getMessage());
			} else if (exception instanceof PermissionException) {
				logger.error("[PermissionException] {}", exception.getMessage(), exception);

				outDTO.setResultMessage(-99, msgSrcAccessor.getMessage("msg.login.session.timeout"));
			} else if (exception instanceof PlatformException) {
				logger.error("[PlatformException] {}", exception.getMessage(), exception);

				outDTO.setResultMessage(-90, msgSrcAccessor.getMessage("msg.exception.platform"));
			} else if (exception instanceof DataAccessException) {
				logger.error("[DataAccessException] {}", exception.getMessage(), exception);

				outDTO.setResultMessage(-80, msgSrcAccessor.getMessage("msg.exception.dataAccess"));
			} else if (exception instanceof MaxUploadSizeExceededException) {
				MaxUploadSizeExceededException uploadEx = (MaxUploadSizeExceededException) exception;

				logger.error("[MaxUploadSizeExceededException] {}", uploadEx.getMessage(), uploadEx);

				outDTO.setResultMessage(-210, msgSrcAccessor.getMessage("msg.upload.size.limit",
						new Object[] { uploadEx.getMaxUploadSize() }));
			} else {
				logger.error("[{}] {}", exception.getClass().getSimpleName(), exception.getMessage(), exception);

				outDTO.setResultMessage(-1, msgSrcAccessor.getMessage("msg.exception"));
			}

			mav.addObject(xpDtoId, outDTO);
		} else {
			mav = new ModelAndView("error");

			mav.addObject("exceptionName", exception.getClass().getSimpleName());
			mav.addObject("message", exception.getMessage());

			logger.error("[{}] {}", exception.getClass().getSimpleName(), exception.getMessage(), exception);
		}

		return mav;
	}
}
